package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.pro.activity.pojo.dto.ActivityGetDTO;
import com.xbongbong.pro.activity.pojo.dto.ActivityUpgradeHistoryDTO;
import com.xbongbong.pro.activity.pojo.vo.ActivityGetVO;
import com.xbongbong.pro.activity.pojo.vo.ActivityUpgradeHistoryVO;
import com.xbongbong.pro.domain.entity.ActivityCorpEntity;
import com.xbongbong.pro.domain.entity.ActivityEntity;
import com.xbongbong.pro.enums.ActivityTypeEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.model.ActivityCorpModel;
import com.xbongbong.saas.model.ActivityModel;
import com.xbongbong.saas.service.ActivityService;
import com.xbongbong.sys.domain.entity.CompanyEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.CompanyModel;
import com.xbongbong.sys.model.UserModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @description: 公告
 * @Author: hongxiao
 * @date: 2019-03-25 16:43
 * @since v1.0
 */
@Service("activityService")
public class ActivityServiceImpl implements ActivityService {
    private static final Logger LOG = LoggerFactory.getLogger(ActivityServiceImpl.class);
    @Resource
    private ActivityModel activityModel;
    @Resource
    private UserModel userModel;
    @Resource
    private ActivityCorpModel activityCorpModel;
    @Resource
    private CompanyModel companyModel;
    @Resource
    private PaasRedisHelper paasRedisHelper;

    @Override
    public ActivityGetVO getActivity(ActivityGetDTO activityGetDTO) throws XbbException {
        ActivityGetVO getVO = new ActivityGetVO();
        //　默认需要弹窗
        getVO.setHasPop(true);

        String corpid = activityGetDTO.getCorpid();
        String userId = activityGetDTO.getUserId();

        UserVO loginUser = activityGetDTO.getLoginUser();
        // 是否为停服公告
        ActivityEntity stopActivity = getUpdatingActivity(ActivityTypeEnum.STOP_SERVICE.getCode());
        if (Objects.nonNull(stopActivity)) {
            //该公司是否有效
            if(!companyEffective(stopActivity, corpid) || !userEffective(stopActivity, loginUser)) {
                return null;
            }

            //活动是否已被访问过
            if (isRead(corpid, userId, activityGetDTO.getPlatform(), stopActivity.getId())) {
                return null;
            }

           activityCorpModel.save(stopActivity.getId(), corpid, userId, "", activityGetDTO.getPlatform());
            BeanUtil.copyProperties(stopActivity, getVO);
            getVO.setActiveAlias(ActivityTypeEnum.STOP_SERVICE.getAlias());
            getVO.setClose(true);
            getVO.setTopShow(false);
            return getVO;
        }
        // 是否为升级中的公告
        ActivityEntity updatingActivity = getUpdatingActivity(ActivityTypeEnum.VERSION_UPDATING.getCode());
        if (Objects.nonNull(updatingActivity)) {
            BeanUtil.copyProperties(updatingActivity, getVO);
            getVO.setActiveAlias(ActivityTypeEnum.VERSION_UPDATING.getAlias());
            getVO.setClose(false);
            getVO.setTopShow(true);
            if(!companyEffective(updatingActivity, corpid)) {
                getVO.setHasPop(false);
                return getVO;
            }
            return getVO;
        }


        ActivityEntity activity = getActivityByUser(loginUser, activityGetDTO.getPlatform(), ActivityTypeEnum.VERSION_UPGRADE.getCode());
        if (activity == null) {
            return null;
        }
       activityCorpModel.save(activity.getId(), corpid, userId, "", activityGetDTO.getPlatform());

        BeanUtil.copyProperties(activity, getVO);
        getVO.setActiveAlias(ActivityTypeEnum.VERSION_UPGRADE.getAlias());
        getVO.setClose(true);
        getVO.setTopShow(false);

        return getVO;
    }

    @Override
    public ActivityUpgradeHistoryVO upgradeHistory(ActivityUpgradeHistoryDTO upgradeHistoryDTO) throws XbbException {
        return null;
    }

    /**
     * 员工能参与的活动
     *
     * @param loginUser 用户实体
     * @param platform 平台
     * @return
     * @throws
     * @author hongxiao
     * @date: 2019-04-15 10:54
     * @version v1.0
     * @since v1.0
     */
    @Override
    public ActivityEntity getActivityByUser(UserVO loginUser, String platform, Integer activityType) {
        //取出该公司的所有在有效期的版本升级
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("nowTime", DateUtil.getInt());
        param.put("type", activityType);
        param.put("del", DelEnum.NORMAL.getDel());
        List<ActivityEntity> activityList = activityModel.findEntitys(param);
        ActivityEntity activity = null;

        //没有在有效时间内的活动
        if (activityList.isEmpty()) {
            return activity;
        }

        String corpid = loginUser.getCorpid();

        for (ActivityEntity activityEntity : activityList) {
            //该公司是否有效
            if(!companyEffective(activityEntity, corpid)) {
                continue;
            }

            //对员工是否有效
            if(!userEffective(activityEntity, loginUser)) {
                continue;
            }
            //活动是否已被访问过
            if (isRead(corpid, loginUser.getUserId(), platform, activityEntity.getId())) {
                continue;
            }

            //找到第一个活动，直接返回
            activity = activityEntity;
            break;
        }
        return activity;
    }

    /**
     * 对公司是否有效
     * @param activityEntity
     * @param corpid
     * 创建时间 2019/10/24 7:37 PM
     * 修改时间 2019/10/24 7:37 PM
     * @author chy
     * @since v1.1.3
     * @version v1.1.3
     */
    private boolean companyEffective(ActivityEntity activityEntity, String corpid) {

        if (Objects.equals(activityEntity.getCorpLimit(), BasicConstant.ZERO)) {
            return true;
        } else if (Objects.equals(activityEntity.getCorpLimit(), BasicConstant.TWO)) {
            // 黑名单公司，公告无效
            String partnerCorpids = activityEntity.getPartnerCorpids();
            List<String> partnerCorpidList = JsonHelperUtil.parseArray(partnerCorpids, String.class);
            return !(Objects.nonNull(partnerCorpidList) && !partnerCorpidList.isEmpty() && partnerCorpidList.contains(corpid));
        }

        CompanyEntity company = companyModel.getByKey(corpid);

        //指定公司限制
        String partnerCorpids = activityEntity.getPartnerCorpids();
        if (!companyEffective4Corpid(partnerCorpids, corpid)) {
            return false;
        }

        //指定渠道限制
        String partnerAuthChannels = activityEntity.getPartnerAuthChannels();
        String authChannel = company.getAuthChannel();
        if (!companyEffective4AuthChannel(partnerAuthChannels, authChannel)) {
            return false;
        }

        //需要企业认证
        Integer partnerIsAuthenticated = activityEntity.getPartnerIsAuthenticated();
        Integer isAuthenticated = company.getIsAuthenticated();
        //需要企业认证，但公司没有企业认证
        if (Objects.equals(partnerIsAuthenticated, BasicConstant.ONE)) {
            if (Objects.equals(isAuthenticated, BasicConstant.ZERO)) {
                return false;
            }
        }

        //试用公司限制
        Integer partnerIsTrial = activityEntity.getPartnerIsTrial();
        if (!companyEffective4Trial(partnerIsTrial, company)) {
            return false;
        }

        return true;
    }

    /**
     * 是否需要试用公司
     * @param partnerIsTrial
     * @param company
     * @return
     * 创建时间 2019/10/25 2:22 PM
     * 修改时间 2019/10/25 2:22 PM
     * @author chy
     * @since v1.1.3
     * @version v1.1.3
     */
    private boolean companyEffective4Trial(Integer partnerIsTrial, CompanyEntity company) {

        //不需要试用公司
        if (Objects.equals(partnerIsTrial,BasicConstant.ZERO )) {
            return true;
        }

        Integer vipNum = company.getVipNum();
        //需要试用公司，但当前公司不是试用公司
        if (vipNum != null && vipNum > 0) {
            return false;
        }
        return true;
    }

    /**
     * 指定渠道限制,对于authChannel是否有效
     * @param partnerAuthChannels
     * @param authChannel
     * @return
     * 创建时间 2019/10/25 9:55 AM
     * 修改时间 2019/10/25 9:55 AM
     * @author chy
     * @since v1.1.3
     * @version v1.1.3
     */
    private boolean companyEffective4AuthChannel(String partnerAuthChannels, String authChannel) {
        List<String> partnerAuthChannelList = JSON.parseArray(partnerAuthChannels, String.class);
        //未设置时，所有渠道有效
        if (partnerAuthChannelList == null || partnerAuthChannelList.isEmpty()) {
            return true;
        }

        if (StringUtil.isEmpty(authChannel)) {
            return false;
        }

        //设置了渠道，包含在设置中
        if (partnerAuthChannelList.contains(authChannel)) {
            return true;
        }

        return false;
    }

    /**
     * 指定公司限制,对于corpid是否有效
     * @param partnerCorpids
     * @param corpid
     * @return
     * 创建时间 2019/10/25 9:44 AM
     * 修改时间 2019/10/25 9:44 AM
     * @author chy
     * @since v1.1.3
     * @version v1.1.3
     */
    private boolean companyEffective4Corpid(String partnerCorpids, String corpid){
        List<String> partnerCorpidList = JSON.parseArray(partnerCorpids, String.class);
        //未设置时，所有公司有效
        if (partnerCorpidList == null || partnerCorpidList.isEmpty()) {
            return true;
        }

        //设置了公司，包含在设置中
        if (partnerCorpidList.contains(corpid)) {
            return true;
        }

        return false;
    }

    /**
     * 对该员工是否有效
     * @param activityEntity
     * @param loginUser
     * @return
     * 创建时间 2019/10/24 7:39 PM
     * 修改时间 2019/10/24 7:39 PM
     * @author chy
     * @since v1.1.3
     * @version v1.1.3
     */
    private boolean userEffective(ActivityEntity activityEntity, UserVO loginUser) {

        Integer userLimit = activityEntity.getUserLimit();

        //没有员工限制
        if (Objects.equals(userLimit, BasicConstant.ZERO)) {
            return true;
        }

        //限制老板，当前人不为老板
        Integer partnerIsBoss = activityEntity.getPartnerIsBoss();
        if (Objects.equals(partnerIsBoss, BasicConstant.ONE)) {
            if (!loginUser.isBoss()) {
                return false;
            }
        }

        //限制管理员，当前人不为管理员
        Integer partnerIsAdmin = activityEntity.getPartnerIsAdmin();
        if (Objects.equals(partnerIsAdmin, BasicConstant.ONE)) {
            if (!loginUser.isAdmin()) {
                return false;
            }
        }

        return true;
    }

    @Override
    public ActivityEntity getLastActivity(Integer type, String corpid){
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("type", type);
        param.put("start", BasicConstant.ZERO);
        param.put("pageNum", BasicConstant.ONE);
        param.put("del", DelEnum.NORMAL.getDel());
        param.put("orderByStr", "update_time desc");
        List<ActivityEntity> activityList = activityModel.findEntitys(param);

        if (activityList.isEmpty()) {
            return null;
        }

        ActivityEntity activity = null;
        for (ActivityEntity entity : activityList) {
            //该公司是否有效
            if(!companyEffective(entity, corpid)) {
                continue;
            }
            activity = entity;
            break;
        }

        return activity;
    }

    /**
     * 获取升级中公告
     *
     * @param activityType 公告类型
     * @throws
     * @return
     * @author hongxiao
     * @date 2020-01-08 14:56
     * @since v4.11.0
     * @version v4.11.0
     */
    private ActivityEntity getUpdatingActivity(Integer activityType) {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("nowTime", DateUtil.getInt());
        param.put("type", activityType);
        param.put("del", DelEnum.NORMAL.getDel());
        List<ActivityEntity> activityList = activityModel.findEntitys(param);
        if (activityList.isEmpty()) {
            return null;
        }

        return activityList.get(0);
    }

    /**
     * 判断活动对userEntity、mobile是否有效
     *
     * @param activity                活动实体
     * @param userEntity              用户实体
     * @param mobile                  手机号
     * @param companyEntity           公司实体
     * @param userActivityCorpList    公司活动记录
     * @param companyActivityCorpList 公司活动记录
     * @return
     * @throws
     * @author hongxiao
     * @date: 2019-04-15 11:07
     * @version v1.0
     * @since v1.0
     */
    private boolean activityEnable(ActivityEntity activity, UserEntity userEntity, String mobile, CompanyEntity companyEntity,
                                   List<ActivityCorpEntity> userActivityCorpList, List<ActivityCorpEntity> companyActivityCorpList) {
        if (!activityMobileEnable(activity, mobile)) {
            return false;
        }

        if (!activityUserEnable(activity, userEntity, userActivityCorpList)) {
            return false;
        }

        if (!activityCompanyEnable(activity, companyEntity, companyActivityCorpList)) {
            return false;
        }

        return true;
    }

    /**
     * 判断该手机号是否参与过活动
     *
     * @param activity 活动实体
     * @param mobile   手机号
     * @return
     * @throws
     * @author hongxiao
     * @date: 2019-04-15 11:28
     * @version v1.0
     * @since v1.0
     */
    private boolean activityMobileEnable(ActivityEntity activity, String mobile) {
        // 不在领取阶段(非领取阶段获取不到手机号)
        if (StringUtil.isEmpty(mobile)) {
            return true;
        }

        if (activity.getType().equals(ActivityTypeEnum.CARD_COUPON.getCode())) {
            // 判断公司是否已参与
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("activityId", activity.getId());
            param.put("mobile", mobile);
            param.put("del", DelEnum.NORMAL.getDel());
            Integer count = activityCorpModel.getEntitysCount(param);
            // 参与过返回false
            return count <= 0;
        }

        return true;
    }

    /**
     * 判断该活动是否对该人员有效
     *
     * @param activity         活动实体
     * @param userEntity       用户实体
     * @param activityCorpList 公司活动记录列表
     * @return
     * @throws
     * @author hongxiao
     * @date: 2019-04-15 11:29
     * @version v1.0
     * @since v1.0
     */
    private boolean activityUserEnable(ActivityEntity activity, UserEntity userEntity, List<ActivityCorpEntity> activityCorpList) {
        if (userEntity == null) {
            return false;
        }

        // 判断用户是否参与过。版本更新，用户参与一次
        if (activity.getType().equals(ActivityTypeEnum.VERSION_UPGRADE.getCode())) {
            int count = 0;
            for (ActivityCorpEntity activityCorp : activityCorpList) {
                if (Objects.equals(activityCorp.getActivityId(), activity.getId()) &&
                        Objects.equals(activityCorp.getUserId(), userEntity.getUserId())) {
                    count++;
                }
            }
            if (count > 0) {
                return false;
            }
        }
        // 没有人员限制
        if (activity.getUserLimit() == 0) {
            return true;
        }
        boolean maxDatePermission = userModel.isBoss(userEntity);
        if (activity.getPartnerIsAdmin() == 1 && maxDatePermission) {
            return true;
        }
        if (activity.getPartnerIsBoss() == 1 && maxDatePermission) {
            return true;
        }
        List<String> activityRoles = JSONArray.parseArray(activity.getPartnerRoles(), String.class);
        // role |1|
        for (String role : activityRoles) {
            if (userEntity.getRoleIds().contains(role)) {
                return true;
            }
        }
        return false;
    }


    /**
     * 判断该活动是否是该公司的有效活动----------若没有进入活动逻辑，不会执行数据库操作，耗时短
     * 默认活动收集手机号在前期已存在，在tb_activity_corp表中没有数据，用该方法判断活动是否有效
     *
     * @param activity         活动实体
     * @param companyEntity    公司实体
     * @param activityCorpList 公司活动记录列表
     * @return
     * @throws
     * @author hongxiao
     * @date: 2019-04-15 15:02
     * @version v1.0
     * @since v1.0
     */
    private boolean activityCompanyEnable(ActivityEntity activity, CompanyEntity companyEntity, List<ActivityCorpEntity> activityCorpList) {
        String corpid = companyEntity.getCorpid();
        String authChannel = companyEntity.getAuthChannel();
        Integer isAuthenticated = companyEntity.getIsAuthenticated();
        long corpAddTime = activity.getCorpAddTime();
        long addTime = companyEntity.getAddTime();
        if (addTime < corpAddTime) {
            return false;
        }
        // 优惠卷公司只能参与一次
        if (activity.getType().equals(ActivityTypeEnum.CARD_COUPON.getCode()) || activity.getType().equals(ActivityTypeEnum.ZHI_MA_XIN_YONG.getCode())) {
            int count = 0;
            for (ActivityCorpEntity activityCorp : activityCorpList) {
                if (Objects.equals(activityCorp.getActivityId(), activity.getId()) &&
                        Objects.equals(activityCorp.getCorpid(), corpid)) {
                    count++;
                }
            }
            if (count > 0) {
                return false;
            }

            if (activity.getCorpLimit().equals(1) && activity.getPartnerIsAuthenticated().equals(1)) {
                // 获取当前的suiteToken
                String suitTokenStr = paasRedisHelper.getValue("ticket", "suiteToken");
                if (suitTokenStr == null) {
                    return false;
                }
                //同步一次公司数据
                companyModel.updateCompanyInfo(corpid, suitTokenStr);
            }
        }

        // 有限制公司，判断是否是有效活动
        if (activity.getCorpLimit().equals(1)) {
            List<String> corpidList = JSONArray.parseArray(activity.getPartnerCorpids(), String.class);
            List<String> cuthChannelList = JSONArray.parseArray(activity.getPartnerAuthChannels(), String.class);
            if (!corpidList.contains(corpid) && !cuthChannelList.contains(authChannel)) {
                return false;
            }
            if (activity.getPartnerIsAuthenticated().equals(1) && !isAuthenticated.equals(1)) {
                return false;
            }
        }

        // TODO 培训活动使用时，再处理这个方法
//        if(activity.getType().equals(ActivityTypeEnum.DEFAULT.getCode())){
//            //默认手机号码、培训活动,查看培训表是否有该公司的数据
//            Integer trainCount = trainModel.getTrainChanceCount(corpid);
//            if(trainCount > 0){
//                return false;
//            }
//        }

        return true;
    }

    /**
     * 是否已读过
     *
     * @param corpid 公司id
     * @param userId 员工id
     * @param platform 平台
     * @param activityId 公告id
     * @return 是否已读过
     */
    private boolean isRead(String corpid, String userId, String platform, Long activityId) {
        //活动是否已被访问过
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.clear();
        param.put("activityId", activityId);
        param.put(StringConstant.CORPID, corpid);
        param.put("userId", userId);
        param.put("platform", platform);
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        Integer count = activityCorpModel.getEntitysCount(param);
        return count > 0;
    }
}
